import java.util.ArrayList;
import java.util.List;

public class Shoe {
	private List<P> pList = new ArrayList<P>();

	private double realCount;

	private double rCount;

	public double getRealCount() {
		return realCount;
	}

	public void setRealCount(double realCount) {
		this.realCount = realCount;
	}

	public Shoe(int deckNumber) {
		for (int i = 0; i < deckNumber; i++) {
			Deck d = new Deck();
			pList.addAll(d.getpList());
		}

	}

	public Shoe(int deckNumber, int g) {
		for (int i = 0; i < deckNumber; i++) {
			Deck d = new Deck(g);
			pList.addAll(d.getpList());
		}

	}

	private void bjCount(P p1) {
		// if (p1.getNum() == 2 || p1.getNum() == 3 || p1.getNum() == 4 ||
		// p1.getNum() == 6 || p1.getNum() == 5) {
		// realCount++;
		// } else if (p1.getNum() == 14 || p1.getNum() == 13 || p1.getNum() ==
		// 12 || p1.getNum() == 11 || p1.getNum() == 10) {
		// realCount--;
		// }

		if (p1.getNum() == 2) {
			realCount = realCount + 0.7;
		} else if (p1.getNum() == 3) {
			realCount = realCount + 0.8;
		} else if (p1.getNum() == 4) {
			realCount = realCount + 1.1;
		} else if (p1.getNum() == 5) {
			realCount = realCount + 1.5;
		} else if (p1.getNum() == 6) {
			realCount = realCount + 1.4;
		} else if (p1.getNum() == 7) {
			realCount = realCount + 0.4;
		} else if (p1.getNum() == 8) {
		} else if (p1.getNum() == 9) {
			realCount = realCount - 0.4;
		} else if (p1.getNum() >= 10) {
			realCount = realCount - 1.1;
		}

	}

	private void long7Count(P p1) {

		 if (p1.getNum() == 1) {
		 this.realCount = this.realCount + 0.5;
		 } else if (p1.getNum() == 2) {
		 this.realCount = this.realCount - 0.9;
		 } else if (p1.getNum() == 3) {
		 this.realCount = this.realCount - 1.1;
		 } else if (p1.getNum() == 4) {
		 this.realCount = this.realCount - 2.7;
		 } else if (p1.getNum() == 5) {
		 this.realCount = this.realCount - 2.6;
		 } else if (p1.getNum() == 6) {
		 this.realCount = this.realCount - 3.2;
		 } else if (p1.getNum() == 7) {
		 this.realCount = this.realCount - 3.6;
		 } else if (p1.getNum() == 8) {
		 this.realCount = this.realCount + 5.4;
		 } else if (p1.getNum() == 9) {
		 this.realCount = this.realCount + 4.8;
		 } else if (p1.getNum() >= 10) {
		 this.realCount = this.realCount + 0.9;
		 }
		 
//		if (p1.getNum() == 5 || p1.getNum() == 6 || p1.getNum() == 7 || p1.getNum() == 4) {
//			realCount--;
//		} else if (p1.getNum() == 8 || p1.getNum() == 9) {
//			realCount = realCount + 2;
//		}
		rCount = (this.realCount / (pList.size() / 52));

	}

	public P dealRandomCard() {
		int n1 = MathUtil.randomNum(pList.size());
		P p1 = (P) pList.get(n1);
		pList.remove(n1);
		long7Count(p1);
		return p1;
	}

	public double getrCount() {
		return rCount;
	}

	public void setrCount(int rCount) {
		this.rCount = rCount;
	}

	public P dealSpeicalCard(P sp) {
		P rm = null;
		for (P p : pList) {
			if (p.getColor() == sp.getColor() && p.getNum() == sp.getNum()) {
				rm = p;
			}
		}
		if (rm != null) {
			pList.remove(rm);
			return rm;
		}
		return null;
	}

	public P dealSpeicalCard(int i) {
		if(i==10){
			P rm = null;
			for (P p : pList) {
				if ( p.getNum() >=10) {
					rm = p;
					break;
				}
			}
			if (rm != null) {
				pList.remove(rm);
				return rm;
			}
			return null;
			
		}else{
			P rm = null;
			for (P p : pList) {
				if ( p.getNum() ==i) {
					rm = p;
					break;
				}
			}
			if (rm != null) {
				pList.remove(rm);
				return rm;
			}
			return null;
				
		}
	}

	
	public List<P> getpList() {
		return pList;
	}

	private static void mainStep(List<P> dealerPList, List<P> playerPList, Shoe shoe) {
		betcount++;
		icount++;
		boolean doubleBet = false;
		boolean bust = false;
		boolean bj = false;
		boolean splite = false;

		while (true && !bj) {
			if (Player.getStrategy(dealerPList.get(0), playerPList) == Player.HIT) {
				playerPList.add(shoe.dealRandomCard());
			} else if (Player.getStrategy(dealerPList.get(0), playerPList) == Player.SURRENDER) {
				playerPList.add(shoe.dealRandomCard());
			} else if (Player.getStrategy(dealerPList.get(0), playerPList) == Player.DOUBLEBET) {
				doubleBet = true;
				playerPList.add(shoe.dealRandomCard());
				break;
			} else if (Player.getStrategy(dealerPList.get(0), playerPList) == Player.BUST) {
				bust = true;
				break;
			} else if (Player.getStrategy(dealerPList.get(0), playerPList) == Player.HOLD) {
				break;
			} else if (Player.getStrategy(dealerPList.get(0), playerPList) == Player.SPLITE) {
				splite = true;
				break;
			}
		}

		if (splite) {
			List<P> nPList = new ArrayList<P>();
			nPList.add(playerPList.get(0));
			playerPList.remove(0);
			playerPList.add(shoe.dealRandomCard());
			nPList.add(shoe.dealRandomCard());
			mainStep(dealerPList, playerPList, shoe);
			mainStep(dealerPList, nPList, shoe);
			return;
		}

		while (Dealer.isHit(dealerPList)) {
			dealerPList.add(shoe.dealRandomCard());
		}

		int playerPoint = Player.count(playerPList);
		int dealerPoint = Dealer.count(dealerPList);

		int rnum = 0;

		if (bust) {
			rnum = -1;
		} else if (dealerPList.size() == 2 && dealerPoint == 21) {
			rnum = -1;
		} else if (playerPoint == dealerPoint) {
			rnum = 0;
		} else if (dealerPoint > 21) {
			rnum = 1;
		} else if (playerPoint > dealerPoint) {
			rnum = 1;
		} else if (playerPoint < dealerPoint) {
			rnum = -1;
		}

		if (rnum == 1) {
			winCount++;
		} else if (rnum == -1) {
			lossCount++;
		}

		if (doubleBet) {
			money = money + rnum * 2 * times;
		} else {
			money = money + rnum * times;
		}
	}

	private static void bet() {
		// betcount++;
		times = 1;
	}

	private static int icount = 0;

	private static boolean continueShufflerFlag = false;

	private static void mainStep() {
		Shoe shoe = new Shoe(8);

		while (true) {

			List<P> dealerPList = new ArrayList<P>();
			List<P> playerPList = new ArrayList<P>();

			if (continueShufflerFlag) {
				for (int i = 0; i < 20; i++) {
					shoe.dealRandomCard();
				}
			}

			icount++;
			boolean betFlag = false;
			if (shoe.getrCount() >= 5) {
				times = 4;
				betcount++;
				betFlag = true;
			} else if (shoe.getrCount() >= 4) {
				times = 3;
				betcount++;
				betFlag = true;
			} else if (shoe.getrCount() >= 3) {
				times = 2;
				betcount++;
				betFlag = true;
			} else if (shoe.getrCount() >= 2) {
				times = 1;
				betcount++;
				betFlag = true;
			} else {
				betFlag = false;
			}

			// P sp = new P();
			// sp.setColor(1);
			// sp.setNum(14);

			P sp = shoe.dealRandomCard();
			// P sp1 = shoe.dealRandomCard();
			dealerPList.add(sp);
			// dealerPList.add(sp1);
			playerPList.add(shoe.dealRandomCard());
			playerPList.add(shoe.dealRandomCard());

			if (betFlag) {

				boolean surrender = false;
				boolean doubleBet = false;
				boolean bust = false;
				boolean bj = false;
				boolean splite = false;
				int s;
				while (true) {
					s = Player.getStrategy(sp, playerPList);
					if (s == Player.HIT) {
						playerPList.add(shoe.dealRandomCard());
					} else if (s == Player.SURRENDER) {
						surrender = true;
						break;
					} else if (s == Player.DOUBLEBET) {
						doubleBet = true;
						playerPList.add(shoe.dealRandomCard());
						break;
					} else if (s == Player.BUST) {
						bust = true;
						break;
					} else if (s == Player.HOLD) {
						break;
					} else if (s == Player.SPLITE) {
						splite = true;
						break;
					}
				}

				if (splite) {
					if (playerPList.get(0).getNum() == 14) {
						List<P> nPList = new ArrayList<P>();
						nPList.add(shoe.dealRandomCard());
						nPList.add(playerPList.get(0));

						List<P> nPList1 = new ArrayList<P>();
						nPList1.add(shoe.dealRandomCard());
						nPList1.add(playerPList.get(1));

						int p1 = Player.count(nPList);
						int p2 = Player.count(nPList1);
						while (Dealer.isHit(dealerPList)) {
							dealerPList.add(shoe.dealRandomCard());
						}
						int dealerPoint = Dealer.count(dealerPList);
						if (p1 > dealerPoint || dealerPoint >= 22) {
							winCount++;
							money = money + 1 * times;
						} else if (p1 < dealerPoint) {
							lossCount++;
							money = money - 1 * times;
						}
						if (p2 > dealerPoint || dealerPoint >= 22) {
							winCount++;
							money = money + 1 * times;
						} else if (p2 < dealerPoint) {
							lossCount++;
							money = money - 1 * times;
						}
						betcount++;
						return;
					} else {
						List<P> nPList = new ArrayList<P>();
						nPList.add(playerPList.get(0));
						playerPList.remove(0);
						playerPList.add(shoe.dealRandomCard());
						nPList.add(shoe.dealRandomCard());
						mainStep(dealerPList, playerPList, shoe);
						mainStep(dealerPList, nPList, shoe);
						return;
					}

				}

				int playerPoint = Player.count(playerPList);

				while (Dealer.isHit(dealerPList)) {
					dealerPList.add(shoe.dealRandomCard());
				}
				int dealerPoint = Dealer.count(dealerPList);

				boolean dbj = false;
				if (Player.count(dealerPList) == 21 && dealerPList.size() == 2) {
					dbj = true;
				}
				if (Player.count(playerPList) == 21 && playerPList.size() == 2) {
					bj = true;
				}
				if (bj) {

					if (dbj) {
					} else {
						winCount++;
						money = money + 1.5 * times;
					}
					return;
				}

				if (surrender) {
					lossCount++;
					money = money - 0.5 * times;
				} else {

					int rnum = 0;

					if (bust) {
						rnum = -1;
					} else if (dealerPList.size() == 2 && dealerPoint == 21) {
						rnum = -1;
					} else if (playerPoint == dealerPoint) {
						rnum = 0;
					} else if (dealerPoint > 21) {
						rnum = 1;
					} else if (playerPoint > dealerPoint) {
						rnum = 1;
					} else if (playerPoint < dealerPoint) {
						rnum = -1;
					}

					if (rnum == 1) {
						winCount++;
					} else if (rnum == -1) {
						lossCount++;
					}

					if (doubleBet) {
						money = money + rnum * 2 * times;
					} else {
						money = money + rnum * times;
					}
				}
			}

			if (continueShufflerFlag) {
				break;
			} else {
				if (shoe.getpList().size() <= 200) {
					break;
				}
			}

		}
		// }
	}

	private static int winCount = 0;
	private static int lossCount = 0;

	private static double money = 0;

	private static double betcount = 0;

	private static int times = 1;

	private static int runTimes = 10000;

	public static void main(String[] args) {

		for (int i = 0; i < runTimes; i++) {
			mainStep();
		}
		System.out.println(winCount * 1.0 / betcount);
		System.out.println(lossCount * 1.0 / betcount);

		System.out.println(money);
		System.out.println(betcount / icount);
		System.out.println(money * 1.0 / betcount);
	}

}
